<HEAD>
  <SCRIPT SRC="../ganja.js"></SCRIPT>
</HEAD>
<BODY><SCRIPT>
// Create a Clifford Algebra with 3,1 metric for 2D CGA. 
Algebra(3,1,()=>{ 

// Two null vectors to work with (called origin and infinite)
  var ei = 1e4-1e3,           // e-infinite
      eo = 0.5*(1e4+1e3);     // e-origin
  
// Define points, lines, circles using the null basis.  
  var point  = (x,y)=>eo + x*1e1 + y*1e2 + 0.5*(x*x+y*y)*ei,
      line   = (a,b,c)=>!(a*1e1 + b*1e2 + c*ei),
      circle = (x,y,r)=>!(point(x,y) - r**2/2*ei);
  
// Some identities
  var line_through_P_parallel_with_X = (P,X)=>(P^ei)<<X*(P^ei),
      project_point_on_circle        = (P,C)=>(P^ei)<<C*C,
      project_point_on_line          = (P,L)=>P<<L.Normalized*L.Normalized,
      position                       = (X)=>{ X=X/(X^ei); return X/(X<<-ei); },
      radius                         = (X)=>Math.abs(((X<<X).s/((X^ei)**2).s))**.5,
      attitude                       = (X)=>(ei^eo<<(X^ei)).Normalized,
      split                          = (pp)=>position(pp)-radius(pp)*attitude(pp);

// Define some elements.
  var p1 = point(-0.7,0.4), p2 = point(1,-0.5), p3 = point(0,1.5),
      D = circle(1,-1,0.7),
      X = line(0,1,0), Y=()=>p2^p3^ei;
      
// Graph 
  document.body.appendChild(this.graph([
    "2D CGA - drag p1,p2,p3","",                        // title
    0xFF8888, D,                                        // circle
    ()=>position(D), ()=>"D "+(radius(D).toFixed(2)),   // Center,Radius
    0x44AA44, X, "X", Y, "Y",                           // lines
    0x4444FF,
    ()=>line_through_P_parallel_with_X(p1,Y),"p1 // Y", // parallel to line
    ()=>line_through_P_parallel_with_X(p1,D),"p1 // D", // parallel to circle
    0xFF44FF, 
    ()=>split(project_point_on_circle(p1,D)),"p1 on D", // project on circle
    ()=>project_point_on_line(p1,X), "p1 on X",         // project on line
    ()=>project_point_on_line(p1,Y), "p1 on Y",         // project on line
    0x444444,p1,"p1",p2,"p2",p3,"p3",                   // render the points
  ],{conformal:true,grid:true}));                       // conformal flag!  

});
</SCRIPT></BODY>